<template>
    <div class="app-container">
        <h3>业务记录审计规则 Rules Records</h3>
        <el-button type="primary" @click="handleAddRule">新增规则 New Rule</el-button>
        <el-button type="success" @click="handleAudit">
            <span class="text" v-waves style="margin-right: 1em;">
                开始审计 audit</span>
            <el-icon><DArrowRight /></el-icon>
        </el-button>

        <el-progress v-if="auditing" :percentage="100" status="" :indeterminate="true" :duration="2" />

        <el-table :data="auditRules" style="width: 100%;margin-top:30px;" border>
            <el-table-column type="expand">
                <template #default="props">
                    <!-- 🦜 : here show: txhash, registerTime, pid, ppid, fullCommand -->
                    <div class="d0">
                        <h3>详细信息 More Info:</h3>
                        <div style="padding-left: 30px;">
                            <el-row :gutter="20" class="d1">
                                <el-col :span="4"> <el-text type="info" tag="b"> 发起方 <TT>from</TT>: </el-text></el-col>
                                <!-- 🦜 : use tag="b" to make bold-->
                                <el-col :span="6"> <el-text type="info"> {{props.row.from}} </el-text></el-col>

                                <el-col :span="4"> <el-text type="info" tag="b"> 接受方 <TT>to</TT> : </el-text></el-col>
                                <el-col :span="6"> <el-text type="info"> {{props.row.to}} </el-text></el-col>
                            </el-row>

                            <el-row :gutter="20" class="d1">
                                <el-col :span="4"> <el-text type="info" tag="b"> 窗口开始时间 <TT>startTime</TT>: </el-text></el-col>
                                <!-- 🦜 : use tag="b" to make bold-->
                                <el-col :span="6"> <el-text type="info"> {{parseTime(props.row.startTime)}} </el-text></el-col>

                                <el-col :span="4"> <el-text type="info" tag="b"> 窗口结束时间 <TT>untilTime</TT> : </el-text></el-col>
                                <el-col :span="6"> <el-text type="info"> {{parseTime(props.row.endTime)}} </el-text></el-col>
                            </el-row>

                            <el-row :gutter="20" class="d1">
                                <el-col :span="4"> <el-text type="info" tag="b"> 关键词 <TT>key word</TT>: </el-text></el-col>
                                <!-- 🦜 : use tag="b" to make bold-->
                                <el-col :span="6"> <el-text type="info"> {{props.row.keyWord}} </el-text></el-col>

                                <el-col :span="4"> <el-text type="info" tag="b">  <TT>UUID</TT> : </el-text></el-col>
                                <el-col :span="6"> <el-text type="info"> 1211211bx12hbs </el-text></el-col>
                            </el-row>
                        </div>
                    </div>
                </template>
            </el-table-column>

            <el-table-column align="center" label="规则 Id" width="100">
                <template v-slot="scope"> {{ scope.row.id }} </template> </el-table-column>

            <el-table-column align="center" label="规则名称 Name" width="150">
                <template v-slot="scope"> {{ scope.row.name }} </template> </el-table-column>

            <el-table-column align="header-center" label="描述 Description" width="">
                <template v-slot="scope"> {{ scope.row.description }} </template> </el-table-column>

            <el-table-column align="header-center" label="发起方 From" width="120">
                <template v-slot="scope"> {{ scope.row.from }} </template> </el-table-column>

            <el-table-column align="header-center" label="接收方 To" width="120">
                <template v-slot="scope"> {{ scope.row.to }} </template> </el-table-column>

            <el-table-column align="header-center" label="重复 Repeat" width="150">
                <template v-slot="scope"> {{ scope.row.repeat}} </template> </el-table-column>
            <el-table-column align="center" label="操作 Operations" width="150">
                <template v-slot="scope">
                    <el-button type="primary" size="small" @click="handleEditRule(scope.row)">
                        <el-icon :size="size" :color="color">
                            <Edit />
                        </el-icon>
                    </el-button>
                    <el-button type="danger" size="small" @click="handleDeleteRule(scope.row)">
                        <el-icon :size="size" :color="color">
                            <Delete />
                        </el-icon>
                        </el-button>
                </template>
            </el-table-column>

        </el-table>

        <el-dialog v-model="dialogVisible" :title="dialogType === 'edit' ? '编辑规则Edit Rule' : '新增规则New Rule'">
            <el-form :model="editedRule" label-width="180px" label-position="left">
                <el-form-item label="名字 Name">
                    <el-input v-model="editedRule.name" placeholder="---" />
                </el-form-item>

                <el-form-item label="关键词 Keyword">
                    <el-input v-model="editedRule.keyWord" placeholder="---" />
                </el-form-item>

                <el-form-item label="描述 Description">
                    <el-input v-model="editedRule.description" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea"
                              placeholder="---" />
                </el-form-item>

                <el-form-item label="开始时间 Start Time">
                    <el-date-picker v-model="editedRule.startTime" type="datetime" placeholder="" />
                </el-form-item>

                <el-form-item label="结束时间 Until Time">
                    <el-date-picker v-model="editedRule.endTime" type="datetime" placeholder="" />
                </el-form-item>


                <el-form-item label="重复 Repeat">
                    <el-select v-model="editedRule.repeat"
                        placeholder="Select" size="large" style="width: 240px"
                    >
                        <el-option
                            v-for="item in repeatOptions"
                            :key="item.value"
                            :label="item.label"
                            :value="item.value"
                        />
                    </el-select>
                </el-form-item>

                <!-- <el-form-item label="Desc">
                     <el-input v-model="role.description" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea"
                     placeholder="Role Description" />
                     </el-form-item>
                     <el-form-item label="Menus">
                     <el-tree ref="tree" :check-strictly="checkStrictly" :data="routesData" :props="defaultProps" show-checkbox
                     node-key="path" class="permission-tree" />
                     </el-form-item> -->
            </el-form>
            <div style="text-align:right;">
                <el-button type="danger" @click="dialogVisible = false">Cancel</el-button>
                <el-button type="primary" @click="handleSaveRule">Save</el-button>
            </div>
        </el-dialog>

        <h3>业务记录 Business Records</h3>
        <el-container style="margin-left: 16px; margin-bottom: 15px" >
            <el-autocomplete
                v-model="listQuery.from"
                :fetch-suggestions="querySearch"
                clearable
                class="d3"
                style="width: 200px;"
                placeholder="查询用户 Search User"
                @select="handleSelect"
                :prefix-icon="iconSearch"
                @keyup.enter="handleFilter" />


            <div class="d3">
                <!-- <span class="demonstration">With shortcuts</span> -->
                <el-date-picker
                    v-model="dateRange"
                    type="datetimerange"
                    :shortcuts="datetimeShortcuts"
                    range-separator="-"
                    start-placeholder="开始时间"
                    end-placeholder="结束时间"
                />
            </div>
        </el-container>

        <el-table :key="tableKey" v-loading="listLoading" :data="list"
                                  class="main-table"
                                  fit
                                  highlight-current-row
                                  style="width: 100%;"
                                  height="100%"
                                  @sort-change="sortChange"
        >
            <el-table-column type="expand">
                <template #default="props">
                    <!-- 🦜 : here show: txhash, registerTime, pid, ppid, fullCommand -->
                    <div class="d0">
                        <h3>详细信息 More Info:</h3>
                        <div style="padding-left: 30px;">

                            <el-row :gutter="20" class="d1">
                                <el-col :span="4"> <el-text type="info" tag="b"> 发起方 <TT>from</TT>: </el-text></el-col>
                                <!-- 🦜 : use tag="b" to make bold-->
                                <el-col :span="6"> <el-text type="info"> {{props.row.from}} </el-text></el-col>
                                <el-col :span="4"> <el-text type="info" tag="b"> 接受方 <TT>to</TT> : </el-text></el-col>
                                <el-col :span="6"> <el-text type="info"> {{props.row.to}} </el-text></el-col>
                            </el-row>

                            <el-row :gutter="20" class="d1">
                                <el-col :span="4"> <el-text type="info" tag="b"> 开始时间 <TT>startTime</TT>: </el-text></el-col>
                                <!-- 🦜 : use tag="b" to make bold-->
                                <el-col :span="6"> <el-text type="info"> {{parseTime(props.row.time)}} </el-text></el-col>

                            </el-row>
                        </div>
                    </div>
                </template>
            </el-table-column>
            <el-table-column label="ID" prop="id" width="80"> </el-table-column>
            <el-table-column label="发起方 From" prop="from" width="150"> </el-table-column>
            <!-- <el-table-column label="接收方 To" prop="to" width="150"> </el-table-column> -->
            <el-table-column label="类型 Type" prop="type" width="150"> </el-table-column>
            <el-table-column label="操作 Cmd" prop="cmd" width="400"> </el-table-column>
            <el-table-column label="审计结果 Result" prop="auditResult" width="150"> </el-table-column>
            <el-table-column label="审计原因 Audit Reason" prop="auditReason" width="300"> </el-table-column>
        </el-table>

        <!-- <LottieAnimation :animation-data="ChillPeopleJSON" class="anim1" :auto-play="true" :loop="true" :speed="1" ref="anim" /> -->
    <LottieAnimation :animation-data="R1JSON" class="anim r1" :auto-play="true" :loop="true" :speed="0.05" ref="anim" />
    <LottieAnimation :animation-data="R2JSON" class="anim r2" :auto-play="true" :loop="true" :speed="0.02" ref="anim" />
    <LottieAnimation :animation-data="R3JSON" class="anim r3" :auto-play="true" :loop="true" :speed="0.05" ref="anim" />

    <pagination v-show="totalCount>0" :total="totalCount" v-model:page="listQuery.page" v-model:limit="listQuery.limit" @pagination="getList" />
    </div>
</template>

<script setup lang="ts">

 import { DArrowRight } from '@element-plus/icons-vue';
 import { watch, ref, onMounted, defineComponent, markRaw } from 'vue';
 import { Delete, Search, Edit, Download, Calendar } from '@element-plus/icons-vue';
 import vWaves from '@/directive/waves'; // waves directive
 import { parseTime } from '@/utils';
 import Pagination from '@/components/Pagination'; // secondary package based on el-pagination
 import { rGetBussinessRules, rGetBussinessUsers, rGetBussinessRecords, rStartBussinessAudit} from '@/api/hi_api';

 import { LottieAnimation } from "lottie-web-vue";
 import WatermelonJSON from "@/assets/watermelon.json";
 // import ChillPeopleJSON from "@/assets/administration.json";
 import ChillPeopleJSON from "@/assets/peopleChillChecking.json";
 import DrinkingJSON from "@/assets/drinking.json";

 import R1JSON from "@/assets/ShapesLoader.json";
 import R2JSON from "@/assets/ShapesLoader1.json";
 import R3JSON from "@/assets/CircularLoader.json";
 import {Tween, Easing} from '@tweenjs/tween.js';
 import {datetimeShortcuts} from '@/dt';

 let anim = ref();
 /**
  * This is just a simple version of deep copy
  * Has a lot of edge cases bug
  * If you want to use a perfect deep copy, use lodash's _.cloneDeep
  * @param {Object} source
  * @returns {Object}
  */
 function deepClone(source) {
     if (!source && typeof source !== 'object') {
         throw new Error('error arguments deepClone');
     }
     const targetObj = source.constructor === Array ? [] : {};
     Object.keys(source).forEach(keys => {
         if (source[keys] && typeof source[keys] === 'object') {
             targetObj[keys] = deepClone(source[keys]);
         } else {
             targetObj[keys] = source[keys];
         }
     });
     return targetObj;
}

 class AuditRule {
     id: number;
     name: string;
     description: string;
     from: string;
     to: string;
     keyWord: string;
     startTime: Date;
     endTime: Date;
     repeat: string;

      constructor(id: number, name: string, description: string, from: string, to: string,
                  keyWord: string,
                  startTime: number, endTime: number, repeat: string,
      ) {
          this.id = id;
          this.name = name;
          this.description = description;
          this.from = from;
          this.to = to;
          this.keyWord = keyWord;
          this.startTime = new Date(startTime);
          this.endTime = new Date(endTime);
          this.repeat = repeat;
      }
 };

 const repeatOptions = [
     { label: '每天', value: 'day' },
     { label: '每周', value: 'week' },
     { label: '每月', value: 'month' },
     { label: '每年', value: 'year' },
 ];
 let editedRule = ref<AuditRule>(new AuditRule(0, '', '', '', '','', 0, 0, ''));
 const dialogVisible = ref(false);
 const dialogType = ref('new');


 function sleep(sec){
     return new Promise((resolve, reject) => {
         setTimeout(() => {
             resolve(1);
         }, sec * 1000);
     });
 }
 let auditing = ref(false);
 const handleAudit = async () => {
     console.log('🦜 : handleAudit with rules ->', auditRules.value);
     auditing.value = true
     let r = await rStartBussinessAudit(auditRules.value);
     await sleep(2);
     auditing.value = false;
     ElMessage({
             message: '审计完成 Audit Done',
             type: 'success',
             duration: 5000
         })
     await handleFilter();
 };

 const handleAddRule = () => {
     dialogVisible.value = true;
     dialogType.value = 'new';
     let id = auditRules.value.length + 1;
     editedRule.value = new AuditRule(id, '', '', '', '','', 0, 0, '');
 };

 const handleEditRule = (row: AuditRule) => {
     dialogVisible.value = true;
     dialogType.value = 'edit';
     editedRule.value = new AuditRule(row.id, row.name, row.description, row.from, row.to,
         row.keyWord, row.startTime.getTime(), row.endTime.getTime(), row.repeat);
 };

 const handleDeleteRule = (row: AuditRule) => {
     console.log('🦜 : handleDeleteRule ->', row);
     const index = auditRules.value.indexOf(row);
     auditRules.value.splice(index, 1)
 };

 const handleSaveRule = () => {
     console.log('🦜 : handleSaveRule ->', editedRule.value);
     dialogVisible.value = false;
     // 🦜 : add/modify according to id
      let id = editedRule.value.id;
     if (dialogType.value === 'new') {
         auditRules.value.push(editedRule.value);
     }else {
         // replace the one with the same index
         console.log('🦜 : handleSaveRule ->', id);
         for (let i = 0; i < auditRules.value.length; i++) {
             if (auditRules.value[i].id === id) {
                 auditRules.value[i] = editedRule.value;
                 console.log('🦜 : updating rule', editedRule.value)
                 break;
             }
         }
     }

     console.log('🦜 : after saving: auditRules ->', auditRules.value);
 };
 const auditRules = ref<AuditRule[]>([]);


 class BusinessRecord {
     id: number;
     from: string;
     to: string;
     type: string;
     cmd: string;
     time: Date;
     auditResult: string;
     auditReason: string;
     constructor(id: number, from: string, to: string, type: string, cmd: string, time: number,
                  auditResult: string = '', auditReason: string = ''
     ) {
         this.id = id;
         this.from = from;
         this.to = to;
         this.type = type;
         this.cmd = cmd;
         this.time = new Date(time);
          this.auditResult = auditResult;
          this.auditReason = auditReason;
     }
 };

 const list = ref<BusinessRecord[]>([]);

 const totalPage = ref(1);
 const totalCount = ref(1);
 const listLoading = ref(false);

 const getList = async () => {
     let l = await rGetBussinessRecords(listQuery.value);


     let l0 = l.data.voList.map((x, i) => {
         return new BusinessRecord(x.id, x.from, x.to, x.type, x.cmd, x.time, x.auditResult, x.auditReason);
     });

     list.value = l0;
     totalPage.value = l.data.totalPages;
     totalCount.value = l.data.totalCount;
 };


 onMounted(async () => {
     // let response = await fetchUsers();
     let rules = await rGetBussinessRules();
     console.log('🦜 : rules ->', rules);
     auditRules.value = rules.data.map((x, i) => {
         return new AuditRule(x.id, x.name, x.description, x.from, x.to, x.keyWord,
                              x.startTime, x.endTime, x.repeat);
     });
     // users.value = response.data;
     listLoading.value = true;
     await getList();
     listLoading.value = false;
 });

 const sortChange = async (data: any) => {
     const { prop, order } = data;
     console.log('🦜 : sortChange ->', prop, order);
     await getList();
 };

 const dateRange = ref<[Date, Date]>([
     new Date(0),// yesterday
     new Date(),// now
 ]);

 watch(dateRange, async (x) => {
     console.log('🦜: dateRange changed to:', x);
     if (x === null){
         listQuery.value.sinceTime = '';
         listQuery.value.untilTime = '';
     }else{
         listQuery.value.sinceTime = parseTime(x[0], '{y}-{m}-{d} {h}:{i}:{s}');
         listQuery.value.untilTime = parseTime(x[1], '{y}-{m}-{d} {h}:{i}:{s}');
     }
     await handleFilter();
 });

 interface ListQuery {
     page: number; limit: number;
     from: string | undefined;
     to: string | undefined;
     sinceTime: string | null; untilTime: string | null;
     sort: string;
     ascending: boolean;
     // user: string | undefined;
 }

 const listQuery = ref<ListQuery>(
     { page: 1, limit: 20, from: '', to: '',
       sort: '', ascending: false,
       sinceTime: '', untilTime: '' }
 );


 const handleFilter = async () => {
     console.log(`🦜 : handleFilter() with `, listQuery.value);
     await getList();
 };

 const iconSearch = markRaw(Search);


 const handleSelect = (item) => {
     console.log(`🦜 selected user = `, item); // 🦜 : nothing to be done here....
 };


 const tableKey = ref(0);

 const users = ref<string[]>([
      'u1', 'u2', 'u3'
 ]);

 const querySearch = (queryString: string, cb: any) => {// the user list for auto-completion
     const l = users.value;
     let r = queryString ? l.filter(
         (u: string) => u.toLowerCase().includes(queryString.toLowerCase())
     ) : l;
     r = r.map((u: string) => ({ value: u }));
     // an array of {value}
     // call callback function to return suggestions
     cb(r);
 };
</script>

<style lang="scss">
 @use 'base'
</style>

